package cn.iocoder.yudao.module.trade.statistics.controller.admin;

import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.business.basic.pojo.bo.DataComparison;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.api.trade.aftersale.enums.AfterSaleStatusEnum;
import cn.iocoder.yudao.module.api.trade.delivery.enums.DeliveryTypeEnum;
import cn.iocoder.yudao.module.api.trade.order.enums.TradeOrderStatusEnum;
import cn.iocoder.yudao.module.trade.statistics.bo.TradeOrderMemberRankingRespBO;
import cn.iocoder.yudao.module.trade.statistics.bo.TradeOrderProductRankingRespBO;
import cn.iocoder.yudao.module.trade.statistics.bo.TradeSummaryRespBO;
import cn.iocoder.yudao.module.trade.statistics.convert.TradeStatisticsConvert;
import cn.iocoder.yudao.module.trade.statistics.dal.dataobject.TradeStatisticsDO;
import cn.iocoder.yudao.module.trade.statistics.service.AfterSaleStatisticsService;
import cn.iocoder.yudao.module.trade.statistics.service.TradeOrderStatisticsService;
import cn.iocoder.yudao.module.trade.statistics.service.TradeStatisticsService;
import cn.iocoder.yudao.module.trade.statistics.vo.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 交易统计")
@RestController
@RequestMapping("/trade/statistics")
@Validated
@Slf4j
public class TradeStatisticsController {

    @Resource
    private TradeStatisticsService tradeStatisticsService;
    @Resource
    private TradeOrderStatisticsService tradeOrderStatisticsService;
    @Resource
    private AfterSaleStatisticsService afterSaleStatisticsService;

    @GetMapping("/summary")
    @Operation(summary = "获得交易统计")
    @PreAuthorize("@ss.hasPermission('trade:statistics:query')")
    public CommonResult<DataComparison<TradeSummaryRespVO>> getTradeSummaryComparison() {
        // 1.1 昨天的数据
        TradeSummaryRespBO yesterdayData = tradeStatisticsService.getTradeSummaryByDays(-1);
        // 1.2 前天的数据（用于对照昨天的数据）
        TradeSummaryRespBO beforeYesterdayData = tradeStatisticsService.getTradeSummaryByDays(-2);

        // 2.1 本月数据
        TradeSummaryRespBO monthData = tradeStatisticsService.getTradeSummaryByMonths(0);
        // 2.2 上月数据（用于对照本月的数据）
        TradeSummaryRespBO lastMonthData = tradeStatisticsService.getTradeSummaryByMonths(-1);
        // 拼接数据
        return success(TradeStatisticsConvert.INSTANCE.convert(yesterdayData, beforeYesterdayData, monthData, lastMonthData));
    }

    @GetMapping("/analyse")
    @Operation(summary = "获得交易状况统计")
    @PreAuthorize("@ss.hasPermission('trade:statistics:query')")
    public CommonResult<DataComparison<TradeTrendSummaryRespVO>> getTradeStatisticsAnalyse(TradeTrendReqVO reqVO) {
        return success(tradeStatisticsService.getTradeStatisticsAnalyse(ArrayUtil.get(reqVO.getTimes(), 0),
                ArrayUtil.get(reqVO.getTimes(), 1)));
    }

    @GetMapping("/list")
    @Operation(summary = "获得交易状况明细")
    @PreAuthorize("@ss.hasPermission('trade:statistics:query')")
    public CommonResult<List<TradeTrendSummaryRespVO>> getTradeStatisticsList(TradeTrendReqVO reqVO) {
        List<TradeStatisticsDO> list = tradeStatisticsService.getTradeStatisticsList(ArrayUtil.get(reqVO.getTimes(), 0),
                ArrayUtil.get(reqVO.getTimes(), 1));
        return success(TradeStatisticsConvert.INSTANCE.convertList(list));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出获得交易状况明细 Excel")
    @PreAuthorize("@ss.hasPermission('trade:statistics:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportTradeStatisticsExcel(TradeTrendReqVO reqVO, HttpServletResponse response) throws IOException {
        List<TradeStatisticsDO> list = tradeStatisticsService.getTradeStatisticsList(ArrayUtil.get(reqVO.getTimes(), 0),
                ArrayUtil.get(reqVO.getTimes(), 1));
        // 导出 Excel
        List<TradeTrendSummaryRespVO> voList = TradeStatisticsConvert.INSTANCE.convertList(list);
        List<TradeTrendSummaryExcelVO> data = TradeStatisticsConvert.INSTANCE.convertList02(voList);
        ExcelUtils.write(response, "交易状况.xls", "数据", TradeTrendSummaryExcelVO.class, data);
    }

    @GetMapping("/order-count")
    @Operation(summary = "获得交易订单数量")
    @PreAuthorize("@ss.hasPermission('trade:statistics:query')")
    public CommonResult<TradeOrderCountRespVO> getOrderCount() {
        // 订单统计
        Long undeliveredCount = tradeOrderStatisticsService.getCountByStatusAndDeliveryType(
                TradeOrderStatusEnum.PAID.getStatus(), DeliveryTypeEnum.EXPRESS.getType());
        // TODO @疯狂：订单支付后，如果是门店自提的，需要 updateWhenPaid 成 DELIVERED；；目前还没搞~~突然反应过来
        Long pickUpCount = tradeOrderStatisticsService.getCountByStatusAndDeliveryType(
                TradeOrderStatusEnum.DOING.getStatus(), DeliveryTypeEnum.PICK_UP.getType());
        // 售后统计
        Long afterSaleApplyCount = afterSaleStatisticsService.getCountByStatus(AfterSaleStatusEnum.APPLY);
        // 拼接返回
        TradeOrderCountRespVO respVO = new TradeOrderCountRespVO();
        respVO.setUndelivered(undeliveredCount);
        respVO.setPickUp(pickUpCount);
        respVO.setAfterSaleApply(afterSaleApplyCount);
        return success(respVO);
    }

    @GetMapping("/order-comparison")
    @Operation(summary = "获得交易订单数量")
    @PreAuthorize("@ss.hasPermission('trade:statistics:query')")
    public CommonResult<DataComparison<TradeOrderSummaryRespVO>> getOrderComparison() {
        return success(tradeOrderStatisticsService.getOrderComparison());
    }

    @GetMapping("/order-count-trend")
    @Operation(summary = "获得订单量趋势统计")
    @PreAuthorize("@ss.hasPermission('trade:statistics:query')")
    public CommonResult<List<DataComparison<TradeOrderTrendRespVO>>> getOrderCountTrendComparison(@Valid TradeOrderTrendReqVO reqVO) {
        return success(tradeOrderStatisticsService.getOrderCountTrendComparison(reqVO));
    }

    @GetMapping("/ranking/product-sale")
    @Operation(summary = "获得产品销售排行榜")
    @Parameter(name = "limit", description = "排行榜数量", required = true, example = "15")
    @PermitAll
    public CommonResult<List<TradeOrderProductRankingRespBO>> getProductSaleRanking(@RequestParam(value = "limit", defaultValue = "15") Integer limit) {
        return success(tradeOrderStatisticsService.getOrderProductRanking(limit));
    }

    @GetMapping("/ranking/member-consume")
    @Operation(summary = "获得用户消费排行榜")
    @Parameter(name = "limit", description = "排行榜数量", required = true, example = "15")
    @PermitAll
    public CommonResult<List<TradeOrderMemberRankingRespBO>> getMemberConsumeRanking(@RequestParam(value = "limit", defaultValue = "15") Integer limit) {
        return success(tradeOrderStatisticsService.getOrderMemberRanking(limit));
    }

}
